package com.yhn.init.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yhn.init.common.DeleteRequest;
import com.yhn.init.common.ErrorCode;
import com.yhn.init.exception.BusinessException;
import com.yhn.init.exception.ThrowUtils;
import com.yhn.init.mapper.ApprovalsMapper;
import com.yhn.init.mapper.BoardsMapper;
import com.yhn.init.mapper.HardwareMapper;
import com.yhn.init.mapper.OrdersMapper;
import com.yhn.init.model.bo.OrdersApprovalsBO;
import com.yhn.init.model.dto.approvals.ApprovalsAddRequest;
import com.yhn.init.model.dto.approvals.ApprovalsPurchaseRequest;
import com.yhn.init.model.dto.approvals.ApprovalsQueryRequest;
import com.yhn.init.model.dto.approvals.ApprovalsRequest;
import com.yhn.init.model.entity.*;
import com.yhn.init.model.enums.OrderStatusEnum;
import com.yhn.init.model.enums.ProductStatusEnum;
import com.yhn.init.model.vo.ApprovalsVO;
import com.yhn.init.service.ApprovalsService;
import com.yhn.init.service.PurchaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yhnyhn123
 */
@Slf4j
@Service("approvalsService")
public class ApprovalsServiceImpl extends ServiceImpl<ApprovalsMapper, Approvals> implements ApprovalsService {

    @Resource
    private OrdersMapper ordersMapper;
    @Resource
    private BoardsMapper boardsMapper;
    @Resource
    private HardwareMapper hardwareMapper;
    @Resource
    private PurchaseService purchaseService;


    @Override
    public Page<ApprovalsVO> queryPage(ApprovalsQueryRequest approvalsQueryRequest) {
        if (approvalsQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long current = approvalsQueryRequest.getCurrent();
        long size = approvalsQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
        Page<Approvals> approvalsPage = this.page(new Page<>(current, size),
                this.getQueryWrapper(approvalsQueryRequest));
        Page<ApprovalsVO> approvalsVOPage = new Page<>(current, size, approvalsPage.getTotal());
        List<ApprovalsVO> approvalsVO = this.getApprovalsVO(approvalsPage.getRecords());
        approvalsVOPage.setRecords(approvalsVO);
        return approvalsVOPage;
    }


    @Override
    public QueryWrapper<Approvals> getQueryWrapper(ApprovalsQueryRequest approvalsQueryRequest) {
        QueryWrapper<Approvals> queryWrapper = new QueryWrapper<>();
        // 如果请求对象为空，直接返回一个空的查询包装器
        if (approvalsQueryRequest == null) {
            return queryWrapper;
        }
        // 从请求对象中获取各项查询条件
        Long id = approvalsQueryRequest.getId();
        queryWrapper.eq(id != null && id > 0, "id", id);
        return queryWrapper;
    }

    /**
     * 获取脱敏对象集合
     *
     * @param approvalsList 查询请求
     * @return 脱敏对象集合
     */
    @Override
    public List<ApprovalsVO> getApprovalsVO(List<Approvals> approvalsList) {
        if (CollUtil.isEmpty(approvalsList)) {
            return new ArrayList<>();
        }
        return approvalsList.stream().map(this::getApprovalsVO).collect(Collectors.toList());
    }


    /**
     * 将对象转化为脱敏对象
     *
     * @param approvals 原对象
     * @return 脱敏对象
     */
    @Override
    public ApprovalsVO getApprovalsVO(Approvals approvals) {
        if (approvals == null) {
            return null;
        }
        ApprovalsVO approvalsVO = new ApprovalsVO();
        BeanUtils.copyProperties(approvals, approvalsVO);
        return approvalsVO;
    }

    /**
     * 根据ID获取信息
     *
     * @param id id
     * @return 实体信息
     */
    @Override
    public ApprovalsVO getInfoById(Long id) {
        Approvals approvals = this.getById(id);
        if (approvals == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "没有对应的信息");
        }
        return getApprovalsVO(approvals);
    }

    /**
     * 保存信息
     *
     * @param approvalsAddRequest 添加请求
     * @return 新生成的ID
     */
    @Override
    @Transactional
    public Long saveApprovals(ApprovalsAddRequest approvalsAddRequest) {
        if (approvalsAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Approvals approvals = new Approvals();
        BeanUtils.copyProperties(approvalsAddRequest, approvals);
        boolean result = this.save(approvals);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return approvals.getId();
    }


    /**
     * 修改信息
     *
     * @param approvalsUpdateRequest 修改请求
     * @return 是否修改成功
     */
    @Override
    @Transactional
    public Boolean updateApprovals(ApprovalsRequest approvalsUpdateRequest) {
        if (approvalsUpdateRequest == null || approvalsUpdateRequest.getOrderId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Approvals approvals = new Approvals();
        BeanUtils.copyProperties(approvalsUpdateRequest, approvals);
        long id = approvalsUpdateRequest.getOrderId();
        // 判断是否存在
        Approvals oldApprovals = this.getById(id);
        ThrowUtils.throwIf(oldApprovals == null, ErrorCode.NOT_FOUND_ERROR);
        boolean result = this.updateById(approvals);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return result;
    }

    /**
     * 删除信息
     *
     * @param deleteRequest 删除请求
     * @return 是否修改成功
     */
    @Override
    public Boolean deleteById(DeleteRequest deleteRequest) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long id = deleteRequest.getId();
        // 判断是否存在
        boolean b = this.removeById(id);
        ThrowUtils.throwIf(!b, ErrorCode.NOT_FOUND_ERROR);
        return b;
    }


    /**
     * 批量删除
     *
     * @param ids 批量删除的IDS
     * @return 是否删除成功
     */
    @Override
    @Transactional
    public Boolean deleteBatchByIds(Long[] ids) {
        if (ids == null || ids.length == 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean b = this.removeByIds(Arrays.asList(ids));
        ThrowUtils.throwIf(!b, ErrorCode.NOT_FOUND_ERROR);
        return b;
    }


    @Override
    @Transactional
    public Boolean approvals(ApprovalsRequest approveRequest) {
        if (approveRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        OrdersApprovalsBO ordersInfo = getOrdersInfo(approveRequest);
        Orders orders = ordersInfo.getOrders();
        // 设置订单状态
        orders.setOrderStatus(approveRequest.getIsApproval() ? OrderStatusEnum.APPROVED.getValue() : OrderStatusEnum.REJECTED.getValue());
        // 更新订单状态
        updateOrderStatus(orders);
        // 返回审批结果
        return approveRequest.getIsApproval();
    }

    @Override
    @Transactional
    public Boolean approvalPurchase(ApprovalsPurchaseRequest approvalsPurchaseRequest) {
        if (approvalsPurchaseRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Purchase purchase = purchaseService.getById(approvalsPurchaseRequest.getPurchaseId());
        if (purchase == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "没有对应的采购信息");
        }
        purchase.setStatus(approvalsPurchaseRequest.getIsApproval() ? ProductStatusEnum.APPROVED.getValue() : ProductStatusEnum.REJECTED.getValue());
        return approvalsPurchaseRequest.getIsApproval();
    }

    /**
     * 更新订单状态
     *
     * @param orders 订单对象
     */
    private void updateOrderStatus(Orders orders) {
        ordersMapper.updateById(orders);
    }

    private OrdersApprovalsBO getOrdersInfo(ApprovalsRequest approveRequest) {
        if (approveRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        Long orderId = approveRequest.getOrderId();
        LambdaQueryWrapper<Boards> boardsWrapper = new LambdaQueryWrapper<>();
        boardsWrapper.eq(Boards::getOrderId, orderId);

        LambdaQueryWrapper<Hardware> hardwareWrapper = new LambdaQueryWrapper<>();
        hardwareWrapper.eq(Hardware::getOrderId, orderId);

        Orders orders = ordersMapper.selectById(orderId);
        List<Boards> boardsList = boardsMapper.selectList(boardsWrapper);
        List<Hardware> hardwareList = hardwareMapper.selectList(hardwareWrapper);

        // 判断查询结果是否都非空
        boolean hasEmptyResult = orders == null
                || !CollectionUtil.isNotEmpty(boardsList)
                || !CollectionUtil.isNotEmpty(hardwareList);

        if (hasEmptyResult) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "订单有误");
        }

        OrdersApprovalsBO ordersApprovalsBO = new OrdersApprovalsBO();
        ordersApprovalsBO.setOrders(orders);
        ordersApprovalsBO.setBoardsList(boardsList);
        ordersApprovalsBO.setHardwareList(hardwareList);
        return ordersApprovalsBO;
    }
}
